import "package:share_image_server/export_all.dart";

bool serverRunning = false;
HttpServer? runningServer;
// 写文件函数
void wPid(String content) {
  try {
    final file = File(pidFilePath);
    file.createSync(recursive: true);
    file.writeAsString(content);
  } catch (e) {
    stopServer();
    print("IO权限不足,或IO正在被占用,服务启动失败");
  }
}

// 删除文件函数
void dPid() {
  try {
    final file = File(pidFilePath);
    if (file.existsSync()) {
      file.deleteSync();
    } else {
      print("存在一个非预期操作,服务可能需要你手动停止");
    }
  } catch (e) {
    stopServer();
    print("IO权限不足,或IO正在被占用,服务启动失败");
  }
}

// 服务器启动函数
void server() async {
  // 为每个信号添加一个监听器
  // 添加信号处理器来捕获Ctrl+C
  ProcessSignal.sigint.watch().listen((signal) {
    print('Ctrl+C 被按下，退出程序...');
    dPid();
    exit(0);
  });

  if (serverRunning || checkServerByPid()) {
    print('服务器已在运行中...');
    return;
  }
  config.then((v) async {
    var handler = infoM
        ? Pipeline()
            .addMiddleware(infoMiddleware)
            .addMiddleware(filterMiddleware)
            .addMiddleware(interceptor())
            .addMiddleware(logRequests())
            .addHandler(router.call)
        : Pipeline().addMiddleware(filterMiddleware).addMiddleware(interceptor()).addHandler(router.call);
    runningServer = await serve(handler, host, port);
    serverRunning = true;
    // 写入当前进程 PID 到文件
    wPid(pid.toString());
    logI('${runningServer!.address.host}:${runningServer!.port}');
  });
}

// 停止服务器
void stopServer() async {
  if (!serverRunning || runningServer == null) {
    print('服务器未运行.');
    return;
  }
  await runningServer!.close();
  serverRunning = false;
  runningServer = null;
  dPid();
  print('服务器已停止.');
}

Future<void> stopServerByPid() async {
  final file = File(pidFilePath);
  if (!file.existsSync()) {
    print('进程未找到，无法停止服务器.');
    return;
  }
  final pid = await file.readAsString();
  if (pid.isEmpty) {
    dPid();
    return;
  }

  try {
    // 检查程序是否存在并且程序名与当前程序一致
    if (Platform.isWindows) {
      Process.run('tasklist', []).then((ProcessResult result) {
        if (result.stdout.contains(pid)) {
          print('找到进程，正在停止...');
          Process.run('taskkill', ['/PID', pid, '/F']).then((result) {
            if (result.exitCode == 0) {
              dPid(); // 删除 PID 文件
              print('服务器已停止.');
            } else {
              print('无法停止服务器: ${result.stderr}');
            }
          });
        } else {
          print('未找到运行中的服务器进程.');
        }
      });
    } else {
      Process.run('ps', ['-p', pid]).then((ProcessResult result) {
        if (result.stdout.contains(pid)) {
          print('找到进程，正在停止...');
          Process.run('kill', ['-9', pid]).then((result) {
            if (result.exitCode == 0) {
              dPid(); // 删除 PID 文件
              print('服务器已停止.');
            } else {
              print('无法停止服务器: ${result.stderr}');
            }
          });
        } else {
          print('未找到运行中的服务器进程.');
        }
      });
    }
  } catch (e) {
    print('停止服务器时发生错误: $e');
  }
}

bool checkServerByPid() {
  final file = File(pidFilePath);
  var pid;
  if (!file.existsSync()) {
    return false;
  }
  pid = file.readAsStringSync();
  if (pid.isEmpty) {
    file.deleteSync();
    print("进程异常，进程文件可能被非法篡改");
    return false;
  }

  try {
    // 检查程序是否存在并且程序名与当前程序一致
    if (Platform.isWindows) {
      Process.run('tasklist', []).then((ProcessResult result) {
        if (result.stdout.contains(pid)) {
          return true;
        }
      });
    } else {
      Process.run('ps', ['-p', pid]).then((ProcessResult result) {
        if (result.stdout.contains(pid)) {
          return true;
        }
      });
    }
  } catch (e) {
    print('检测服务时发生错误: $e');
  } finally {
    file.delete();
  }
  return false;
}

void startServerInBackground() async {
  // 启动一个新的 Dart 进程，并传入当前脚本和 --start 标志
  final script = Platform.script.toFilePath();
  final process = await Process.start(
    Platform.executable,
    [script, '--start'],
    mode: ProcessStartMode.detached, // 后台运行
  );

  print('服务器已在后台启动，PID: ${process.pid}');

  // 写入后台进程的 PID 到文件
  wPid(process.pid.toString());
}
